package userlogic

import (
	"context"

	"go-zero-admin/apps/system/cmd/rpc/internal/logic/dept"
	postlogic "go-zero-admin/apps/system/cmd/rpc/internal/logic/post"
	"go-zero-admin/apps/system/cmd/rpc/internal/logic/role"
	userpostlogic "go-zero-admin/apps/system/cmd/rpc/internal/logic/userpost"
	"go-zero-admin/apps/system/cmd/rpc/internal/svc"
	"go-zero-admin/apps/system/cmd/rpc/syspb"

	"github.com/zeromicro/go-zero/core/fx"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/mr"
)

type GetUserComboLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
	getDeptListLogic     *deptlogic.GetDeptListLogic
	getRoleByUidLogic    *rolelogic.GetRoleByUidLogic
	getUserPostListLogic *userpostlogic.GetUserPostListLogic
	getPostListLogic     *postlogic.GetPostListLogic
}

func NewGetUserComboLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserComboLogic {
	return &GetUserComboLogic{
		ctx:                  ctx,
		svcCtx:               svcCtx,
		Logger:               logx.WithContext(ctx),
		getDeptListLogic:     deptlogic.NewGetDeptListLogic(ctx, svcCtx),
		getRoleByUidLogic:    rolelogic.NewGetRoleByUidLogic(ctx, svcCtx),
		getUserPostListLogic: userpostlogic.NewGetUserPostListLogic(ctx, svcCtx),
		getPostListLogic:     postlogic.NewGetPostListLogic(ctx, svcCtx),
	}
}

func (l *GetUserComboLogic) GetUserCombo(in *syspb.GetUserComboReq) (*syspb.GetUserComboResp, error) {
	if len(in.GetUserList()) == 0 {
		return &syspb.GetUserComboResp{UserComboList: nil}, nil
	}

	// 查询出所有部门信息
	deptListResp, err := l.getDeptListLogic.GetDeptList(&syspb.GetDeptListReq{})
	if err != nil {
		return nil, err
	}
	deptList := deptListResp.GetList()

	// 组合用户信息
	var userComboList []*syspb.SysUserCombo
	for _, v := range in.GetUserList() {
		userCombo := new(syspb.SysUserCombo)
		userCombo.User = v

		mr.FinishVoid(func() {
			// 部门
			var dept *syspb.SysDept
			for _, d := range deptList {
				if v.GetDeptId() != d.GetDeptId() {
					continue
				}
				dept = d
				break
			}
			userCombo.Dept = dept
		}, func() {
			// 角色
			roleListResp, e := l.getRoleByUidLogic.GetRoleByUid(&syspb.GetRoleByUidReq{
				UserId: v.GetId(),
			})
			if e != nil || len(roleListResp.GetList()) == 0 {
				return
			}
			userCombo.RoleList = roleListResp.GetList()
		}, func() {
			// 岗位
			postIdListResp, e := l.getUserPostListLogic.GetUserPostList(
				&syspb.GetUserPostListReq{UserId: v.GetId()})
			if e != nil || len(postIdListResp.GetList()) == 0 {
				return
			}

			var postIds []int64
			fx.From(func(source chan<- interface{}) {
				for _, v := range postIdListResp.GetList() {
					source <- v
				}
			}).Map(func(item interface{}) interface{} {
				return item.(*syspb.SysUserPost).PostId
			}).ForEach(func(item interface{}) {
				postIds = append(postIds, item.(int64))
			})

			postListResp, e := l.getPostListLogic.GetPostList(&syspb.GetPostListReq{Ids: postIds})
			if e != nil || len(postListResp.GetList()) == 0 {
				return
			}

			userCombo.PostList = postListResp.GetList()
		})

		userComboList = append(userComboList, userCombo)
	}

	return &syspb.GetUserComboResp{UserComboList: userComboList}, nil
}
